// 扩展 Fabric.js 的滤镜类型定义
declare module 'fabric' {
  namespace filters {
    class SwapColor extends filters.BaseFilter<'SwapColor', {
        colorSource: string;
        colorDestination: string;
      }> {
        colorSource: string;
        colorDestination: string;
        constructor(options?: {
          colorSource?: string;
          colorDestination?: string;
        });
      }
  }
}

/**
 * 创建 SwapColorFilter 的工厂函数
 * 这样可以避免在模块顶层使用 useNuxtApp
 */
export default function createSwapColorFilter(fabric: any) {
  // 创建 SwapColor 滤镜类
  class SwapColorFilter extends fabric.filters.BaseFilter<'SwapColor', { colorSource: string; colorDestination: string }> {
  // type 属性由基类定义，不需要在这里重新定义
  
  /**
   * SwapColor 源颜色，CSS 颜色格式
   */
  colorSource = 'rgb(0, 0, 0)';

  /**
   * SwapColor 目标颜色，CSS 颜色格式
   */
  colorDestination = 'rgb(255, 0, 0)';

  /**
   * 初始化滤镜
   * @param {Object} [options] 选项对象
   */
  constructor(options: any = {}) {
    super(options);
    this.colorSource = options.colorSource || this.colorSource;
    this.colorDestination = options.colorDestination || this.colorDestination;
  }

  /**
   * 应用滤镜到 2D Canvas
   * @param {Object} options
   */
  applyTo2d(options: any) {
    const imageData = options.imageData;
    const data = imageData.data;
    const len = data.length;
    
    // 解析源颜色和目标颜色
    const source = new fabric.Color(this.colorSource).getSource();
    const destination = new fabric.Color(this.colorDestination).getSource();
    
    // 设置颜色匹配的容差值
    const tolerance = 30; // 可以根据需要调整
    
    for (let i = 0; i < len; i += 4) {
      // 计算当前像素与源颜色的差异
      const diffR = Math.abs(data[i] - source[0]);
      const diffG = Math.abs(data[i + 1] - source[1]);
      const diffB = Math.abs(data[i + 2] - source[2]);
      
      // 如果差异在容差范围内，则替换颜色
      if (diffR <= tolerance && diffG <= tolerance && diffB <= tolerance) {
        data[i] = destination[0];
        data[i + 1] = destination[1];
        data[i + 2] = destination[2];
        // 保留原始 alpha 值
      }
    }
  }

  /**
   * 返回滤镜的对象表示
   * @return {Object}
   */
  toObject() {
    return {
      type: 'SwapColor' as const,
      colorSource: this.colorSource,
      colorDestination: this.colorDestination
    };
  }

  /**
   * 获取 WebGL 的 uniform 位置
   */
  getUniformLocations(gl: WebGLRenderingContext, program: WebGLProgram) {
    return {
      uColorSource: gl.getUniformLocation(program, 'colorSource'),
      uColorDestination: gl.getUniformLocation(program, 'colorDestination'),
      uTolerance: gl.getUniformLocation(program, 'tolerance'),
    };
  }

  /**
   * 发送数据到 WebGL 的 uniform 变量
   */
  sendUniformData(gl: WebGLRenderingContext, uniformLocations: any) {
    const source = new fabric.Color(this.colorSource).getSource();
    const destination = new fabric.Color(this.colorDestination).getSource();
    
    // WebGL 中颜色值需要在 0 到 1 之间，而不是 0 到 255
    const normalizedSource = [
      source[0] / 255,
      source[1] / 255,
      source[2] / 255,
      1.0
    ];
    
    const normalizedDest = [
      destination[0] / 255,
      destination[1] / 255,
      destination[2] / 255,
      1.0
    ];
    
    gl.uniform4fv(uniformLocations.uColorSource, normalizedSource);
    gl.uniform4fv(uniformLocations.uColorDestination, normalizedDest);
    gl.uniform1f(uniformLocations.uTolerance, 0.12); // 容差值，可调整
  }

  /**
   * 获取 WebGL 片段着色器源码
   */
  getFragmentSource() {
    return `
      precision highp float;
      uniform sampler2D uTexture;
      uniform vec4 colorSource;
      uniform vec4 colorDestination;
      uniform float tolerance;
      varying vec2 vTexCoord;
      
      void main() {
        vec4 color = texture2D(uTexture, vTexCoord);
        vec3 delta = abs(colorSource.rgb - color.rgb);
        float diff = length(delta);
        
        if (diff < tolerance) {
          // 保留原始 alpha 值
          gl_FragColor = vec4(colorDestination.rgb, color.a);
        } else {
          gl_FragColor = color;
        }
      }
    `;
  }
}

  // 直接返回滤镜类，不注册到 Fabric.js
  return SwapColorFilter;
}